#include"DatabaseController.h" 

#include"Database.h"
#include"DatabaseView.h"
#include"MetaDataEditor.h"

DatabaseController::DatabaseController(QWidget *parent):QObject(parent){
	m_database = new Database(this);
	m_view = new DatabaseView(parent);
	connect(m_database, SIGNAL(contentsChanged(QSet<QString>)), this, SLOT(slotDBContentsChanged(QSet<QString>)));
	connect(m_view, SIGNAL(requestPopulate()), this, SLOT(slotPopulate()));
	connect(m_view, SIGNAL(requestPopulate(const QString &)), this, SLOT(slotPopulate(const QString &)));
	connect(m_view, SIGNAL(requestPopulate(const QString &, const QString &)), this, SLOT(slotPopulate(const QString &, const QString &)));
	MetaDataEditor::addCallbackOnChange(filesEdited, this);
}

DatabaseController::~DatabaseController(){
	m_view = 0;//Child of our parent, so will be deleted by him.
}

QWidget *DatabaseController::widget()const{
	return m_view;
}

void DatabaseController::slotPopulate(){
	QList<QString> artists = m_database->getArtists();
	m_view->populate(artists);
}

void DatabaseController::slotPopulate(const QString &artist){
	QList<QString> albums = m_database->getAlbums(artist);
	m_view->populate(artist, albums);
}

void DatabaseController::slotPopulate(const QString &artist, const QString &album){
	QList<QString> songs = m_database->getSongs(artist, album);
	m_view->populate(artist, album, songs);
}

void DatabaseController::addSongToDB(QPointer<Song> song){
	m_database->addEntry(song);
}

void DatabaseController::slotDBContentsChanged(QSet<QString> changedArtists){
	if(!m_view->rootPopulated())//If artists weren't populated yet, it'll update itself upon population
		return;
	QList<QString> artists = m_database->getArtists();
	QSet<QString> newArtists = changedArtists - QSet<QString>::fromList(artists);
// 	if(newArtists.count())//This is commented, because upon deletion (merge) of artists, it would keep a phantom.
		m_view->ensureArtistsEqual(artists);
	
	for(QSet<QString>::const_iterator it = changedArtists.constBegin(); it != changedArtists.constEnd(); ++it){
		if(m_view->artistPopulated(*it)){
			QList<QString> albums = m_database->getAlbums(*it);
			m_view->ensureAlbumsEqual(*it, albums);
			
			for(int j = 0; j < albums.size(); j++){
				if(m_view->albumPopulated(*it, albums[j])){
					QList<QString> songs = m_database->getSongs(*it, albums[j]);
					m_view->ensureSongsEqual(*it, albums[j], songs);
				}
			}
		}
	}
}

void DatabaseController::filesEdited(void *obj, QList<QString> filepaths){
	DatabaseController *controller = (DatabaseController*) obj;
	controller->filesEdited(filepaths);
}

void DatabaseController::filesEdited(QList<QString> filepaths){
	for(int i = 0; i < filepaths.size(); i++)
		m_view->removeSongWithPath(filepaths[i]);
	m_database->reloadSongs(filepaths);
}
